import { HttpClient } from './http-client.js';

/**
 * 脚本执行器模块
 * 处理JavaScript脚本执行
 */
export class ScriptExecutor {
  constructor() {
    this.executionTimeout = 30000; // 30秒超时
  }

  /**
   * 执行JavaScript脚本
   */
  async executeScript(script, rule, transaction) {
    try {
      const httpClient = new HttpClient(rule.name);
      
      // 创建nf工具对象
      const nf = {
        http: httpClient,
        fetch: globalThis.fetch,
        fs: null, // 出于安全考虑，暂不提供文件系统访问
        path: null, // 出于安全考虑，暂不提供路径操作
        http_client: globalThis.fetch // 保持向后兼容
      };

      // 简化的请求和响应对象
      const req = transaction.request;
      const resp = transaction.response;

      console.log(`🚀 执行规则脚本: ${rule.name}`);
      console.log(`📋 请求: ${req.method} ${req.url}`);
      console.log(`📋 响应: ${resp ? resp.statusCode : '无响应'}`);

      // 设置执行超时
      const timeoutPromise = new Promise((_, reject) => {
        setTimeout(() => reject(new Error('脚本执行超时')), this.executionTimeout);
      });

      // 执行脚本
      const scriptPromise = this.runScript(script, req, resp, nf);
      
      await Promise.race([scriptPromise, timeoutPromise]);

      console.log(`✅ 脚本执行成功: ${rule.name}`);
      
    } catch (error) {
      console.error(`❌ 脚本执行失败 (${rule.name}):`, error);
      throw error;
    }
  }

  /**
   * 运行脚本代码
   */
  async runScript(script, req, resp, nf) {
    // 检查脚本是否包含main函数
    if (script.includes('function main')) {
      // 执行包含main函数的脚本
      const fullScript = `
        ${script}
        
        // 调用main函数
        if (typeof main === 'function') {
          main(req, resp, nf);
        } else {
          console.error('未找到main函数');
        }
      `;
      
      const scriptFunction = new Function('req', 'resp', 'nf', fullScript);
      await scriptFunction(req, resp, nf);
    } else {
      // 直接执行脚本代码
      const scriptFunction = new Function('req', 'resp', 'nf', script);
      await scriptFunction(req, resp, nf);
    }
  }

  /**
   * 验证脚本安全性
   */
  validateScript(script) {
    const warnings = [];
    const errors = [];
    
    // 检查危险函数
    const dangerousFunctions = [
      'eval', 'Function', 'setTimeout', 'setInterval',
      'require', 'import', 'process', 'global', 'globalThis'
    ];
    
    for (const func of dangerousFunctions) {
      if (script.includes(func) && !script.includes(`nf.${func}`)) {
        warnings.push(`脚本包含潜在危险函数: ${func}`);
      }
    }
    
    // 检查文件系统访问
    const fsOperations = ['writeFile', 'readFile', 'unlink', 'mkdir'];
    for (const op of fsOperations) {
      if (script.includes(op)) {
        errors.push(`脚本尝试进行文件系统操作: ${op}`);
      }
    }
    
    // 检查网络访问是否通过nf对象
    if (script.includes('fetch(') && !script.includes('nf.fetch')) {
      warnings.push('建议使用 nf.http 进行网络请求');
    }
    
    return { warnings, errors };
  }

  /**
   * 设置执行超时时间
   */
  setTimeout(timeout) {
    this.executionTimeout = timeout;
  }

  /**
   * 获取执行超时时间
   */
  getTimeout() {
    return this.executionTimeout;
  }
} 